package JasPerl::JSTL::Fmt::FormatNumberTag;

use 5.010;
use strict;
use warnings;

use parent qw(JasPerl::TagExt::JspTag);

use JasPerl::JSTL::Core::Config qw(:fmt);
use JasPerl::JSTL::Fmt::NumberFormat;
use JasPerl::JSTL::Fmt::LocalizationContext;

use JasPerl::PageContext qw(:scopes);

use JasPerl::Util::Number;

my $BUNDLE_CLASS = 'JasPerl::JSTL::Fmt::BundleTag';

my %FORMAT_TYPES = (
    'decimal' => sub {
        JasPerl::JSTL::Fmt::NumberFormat->get_decimal_format($_[0])
    },
    'percent' => sub {
        JasPerl::JSTL::Fmt::NumberFormat->get_percent_format($_[0])
    }
);

sub get_locale {
    my $self = shift;
    my $pc = $self->get_jsp_context();
# TODO: check format locale alg
    if (my $parent = $self->find_ancestor_isa($BUNDLE_CLASS)) {
        return $parent->get_bundle()->get_locale();
    } elsif (my $bundle = JasPerl::JSTL::Fmt::LocalizationContext->get_bundle($pc)) {
        return $bundle->get_locale();
    } else {
        return JasPerl::JSTL::Core::Config->find($pc, FMT_LOCALE);
    }
}

sub get_format {
    my ($self, $locale) = @_;
    if (defined $self->{pattern}) {
        return JasPerl::JSTL::Fmt::NumberFormat->new($self->{pattern}, $locale);
    } elsif (my $method = $FORMAT_TYPES{$self->{type} // 'decimal'}) {
        return $self->$method($locale);
    } else {
        die "no type";
    }
}

sub set_currency_code {
    $_[0]->{currency_code} = $_[1];
}

sub set_currency_symbol {
    $_[0]->{currency_symbol} = $_[1];
}

sub set_grouping_used {
    $_[0]->{grouping_used} = JasPerl::Util::Boolean->from($_[1]);
}

sub set_min_integer_digits {
    $_[0]->{min_integer_digits} = JasPerl::Util::Number->from($_[1]);
}

sub set_max_integer_digits {
    $_[0]->{max_integer_digits} = JasPerl::Util::Number->from($_[1]);
}

sub set_min_fraction_digits {
    $_[0]->{min_fraction_digits} = JasPerl::Util::Number->from($_[1]);
}

sub set_max_fraction_digits {
    $_[0]->{max_fraction_digits} = JasPerl::Util::Number->from($_[1]);
}

sub set_pattern {
    # format->new?
    $_[0]->{pattern} = $_[1];
}

sub set_scope {
    $_[0]->{scope} = JasPerl::PageContext->get_scope_by_name($_[1]);
}

sub set_type {
    $_[0]->{type} = $_[1];
}

sub set_value {
    $_[0]->{value} = JasPerl::Util::Number->from($_[1]);
}

sub set_var {
    $_[0]->{var} = $_[1];
}

sub do_tag {
    my $self = shift;
    my $context = $self->get_jsp_context();
    my $format = $self->get_format($self->get_locale());

    $format->set_grouping_used($self->{grouping_used})
        if defined $self->{grouping_used};
    $format->set_min_integer_digits($self->{min_integer_digits})
        if defined $self->{min_integer_digits};
    $format->set_max_integer_digits($self->{max_integer_digits})
        if defined $self->{max_integer_digits};
    $format->set_min_fraction_digits($self->{min_fraction_digits})
        if defined $self->{min_fraction_digits};
    $format->set_max_fraction_digits($self->{max_fraction_digits})
        if defined $self->{max_fraction_digits};

    # FIXME required value?

    if (defined $self->{value}) {
        my $format = $self->get_format($self->get_locale());
        my $number = $format->format($self->{value});

        if (defined $self->{var}) {
            $context->set_attribute($self->{var}, $number, $self->{scope});
        } else {
            $context->get_out()->print($number);
        }
    } elsif (defined $self->{var}) {
        $context->remove_attribute($self->{var}, $self->{scope} // PAGE_SCOPE);
    }
}

1;
